using System;
using System.Collections.Generic;
using PublicDomain.Copy;
using SevenZSharp.Decoders;
using SevenZSharp.Encoders;

namespace SevenZSharp.Engines
{
   /// <summary>
   /// 
   /// </summary>
   public class ShellEngine : CompressionEngine
   {
      private static readonly List<ShellEngine> s_engines = new List<ShellEngine>();
      private static readonly object s_enginesLock = new object();
      private static string s_7zLocation;
      private string m_7zLocation;

      static ShellEngine()
      {
         s_7zLocation = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\7-Zip\7z.exe";
      }

      /// <summary>
      /// 
      /// </summary>
      public ShellEngine()
      {
         lock (s_enginesLock)
         {
            s_engines.Add(this);
         }
      }

      /// <summary>
      /// 
      /// </summary>
      public static string DefaultSevenZLocation
      {
         get { return s_7zLocation; }
         set
         {
            s_7zLocation = value;
            lock (s_enginesLock)
            {
               foreach (ShellEngine engine in s_engines)
               {
                  engine.SevenZLocation = value;
               }
            }
         }
      }

      /// <summary>
      /// Gets or sets the location of the 7z executable.
      /// </summary>
      /// <value>The seven7 location.</value>
      public virtual string SevenZLocation
      {
         get { return m_7zLocation; }
         set { m_7zLocation = value; }
      }

      /// <summary>
      /// 
      /// </summary>
      protected override void Initialize()
      {
         Encoder = new ShellEncoder(this);
         Decoder = new ShellDecoder(this);
         m_7zLocation = DefaultSevenZLocation;
      }

      /// <summary>
      /// Gets the shell process.
      /// </summary>
      /// <returns></returns>
      public virtual ProcessHelper GetShellProcess()
      {
         ProcessHelper process = new ProcessHelper();
         process.FileName = SevenZLocation;
         return process;
      }

      /// <summary>
      /// Gets the extract shell process.
      /// </summary>
      /// <param name="fileToExtract">The file to extract.</param>
      /// <param name="destinationDir">The destination dir.</param>
      /// <returns></returns>
      public virtual ProcessHelper GetDecodeShellProcess(string fileToExtract, string destinationDir)
      {
         ProcessHelper process = GetShellProcess();
         process.AddArguments("x", "-bd", "-y");
         process.AddArguments("-o" + destinationDir);
         process.AddArguments(fileToExtract);
         return process;
      }

      /// <summary>
      /// Gets the encode shell process.
      /// </summary>
      /// <param name="destinationFile">The destination file.</param>
      /// <param name="filesOrDirectoriesToAdd">The files or directories to add.</param>
      /// <returns></returns>
      public virtual ProcessHelper GetEncodeShellProcess(string destinationFile, params string[] filesOrDirectoriesToAdd)
      {
         ProcessHelper process = GetShellProcess();
         process.AddArguments("a", "-bd", "-y");
         process.AddArguments(destinationFile);

         if (filesOrDirectoriesToAdd != null)
         {
            foreach (string fileOrDirectory in filesOrDirectoriesToAdd)
            {
               process.AddArguments(fileOrDirectory);
            }
         }

         return process;
      }
   }
}